using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Windows.Forms;

namespace HslControls
{
	/// <summary>
	/// 一个柱形图的控件
	/// </summary>
	[Description("一个柱状图控件，支持显示柱状图信息，方便的设置数据源，然后显示出来，支持渐变色")]
	public class HslBarChart : UserControl
	{
		private List<AuxiliaryLine> auxiliary_lines;

		private int value_max_left = -1;

		private int value_min_left = 0;

		private int value_Segment = 5;

		private int[] data_values = null;

		private string[] data_texts = null;

		private Color[] data_colors = null;

		private Brush brush_deep = null;

		private Pen pen_normal = null;

		private Pen pen_dash = null;

		private Color barBackColor = Color.DodgerBlue;

		private bool useGradient = false;

		private Color color_deep = Color.DimGray;

		private Color color_dash = Color.LightGray;

		private StringFormat format_left = null;

		private StringFormat format_right = null;

		private StringFormat format_center = null;

		private bool value_IsRenderDashLine = true;

		private bool isShowBarValue = true;

		private string showBarValueFormat = "{0}";

		private string value_title = "";

		private float barPercentWidth = 0.8f;

		/// <summary> 
		/// 必需的设计器变量。
		/// </summary>
		private IContainer components = null;

		/// <summary>
		/// 获取或设置控件的背景色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的背景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Transparent")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public override Color BackColor
		{
			get
			{
				return base.BackColor;
			}
			set
			{
				base.BackColor = value;
			}
		}

		/// <summary>
		/// 获取或设置当前控件的文本
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前控件的文本")]
		[Category("HslControls")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		[Bindable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public override string Text
		{
			get
			{
				return base.Text;
			}
			set
			{
				base.Text = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置控件的前景色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的前景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Black")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public override Color ForeColor
		{
			get
			{
				return base.ForeColor;
			}
			set
			{
				base.ForeColor = value;
			}
		}

		/// <summary>
		/// 获取或设置坐标轴及相关信息文本的颜色
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置坐标轴及相关信息文本的颜色")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "DimGray")]
		public Color ColorLinesAndText
		{
			get
			{
				return color_deep;
			}
			set
			{
				color_deep = value;
				InitializationColor();
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置本条形图控件是否使用渐进色
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置本条形图控件是否使用渐进色")]
		[Browsable(true)]
		[DefaultValue(false)]
		public bool UseGradient
		{
			get
			{
				return useGradient;
			}
			set
			{
				useGradient = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置柱状图的背景颜色
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置柱状图的背景颜色")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "DodgerBlue")]
		public Color BarBackColor
		{
			get
			{
				return barBackColor;
			}
			set
			{
				barBackColor = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置虚线的颜色
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置虚线的颜色")]
		[Browsable(true)]
		[DefaultValue(typeof(Color), "LightGray")]
		public Color ColorDashLines
		{
			get
			{
				return color_dash;
			}
			set
			{
				color_dash = value;
				pen_dash?.Dispose();
				pen_dash = new Pen(color_dash);
				pen_dash.DashStyle = DashStyle.Custom;
				pen_dash.DashPattern = new float[2]
				{
					5f,
					5f
				};
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置虚线是否进行显示
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置虚线是否进行显示")]
		[Browsable(true)]
		[DefaultValue(true)]
		public bool IsRenderDashLine
		{
			get
			{
				return value_IsRenderDashLine;
			}
			set
			{
				value_IsRenderDashLine = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置图形的纵轴分段数
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图形的纵轴分段数")]
		[Browsable(true)]
		[DefaultValue(5)]
		public int ValueSegment
		{
			get
			{
				return value_Segment;
			}
			set
			{
				value_Segment = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最大值，该值必须大于最小值，该值为负数，最大值即为自动适配。
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图形的左纵坐标的最大值，该值必须大于最小值，该值为负数，最大值即为自动适配。")]
		[Browsable(true)]
		[DefaultValue(-1)]
		public int ValueMaxLeft
		{
			get
			{
				return value_max_left;
			}
			set
			{
				value_max_left = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置图形的纵坐标的最小值，该值必须小于最大值
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图形的左纵坐标的最小值，该值必须小于最大值")]
		[Browsable(true)]
		[DefaultValue(0)]
		public int ValueMinLeft
		{
			get
			{
				return value_min_left;
			}
			set
			{
				if (value < value_max_left)
				{
					value_min_left = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置图标的标题信息
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置图标的标题信息")]
		[Browsable(true)]
		[DefaultValue("")]
		public string Title
		{
			get
			{
				return value_title;
			}
			set
			{
				value_title = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置是否显示柱状图的值文本
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置是否显示柱状图的值文本")]
		[Browsable(true)]
		[DefaultValue(true)]
		public bool IsShowBarValue
		{
			get
			{
				return isShowBarValue;
			}
			set
			{
				isShowBarValue = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置柱状图显示值的格式化信息，可以带单位
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置柱状图显示值的格式化信息，可以带单位")]
		[Browsable(true)]
		[DefaultValue("")]
		public string ShowBarValueFormat
		{
			get
			{
				return showBarValueFormat;
			}
			set
			{
				showBarValueFormat = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置柱状图占平均宽度的百分比，默认0.8，即80%
		/// </summary>
		[Category("HslControls")]
		[Description("获取或设置柱状图占平均宽度的百分比，默认0.8，即80%")]
		[Browsable(true)]
		[DefaultValue(0.8f)]
		public float BarPercentWidth
		{
			get
			{
				return barPercentWidth;
			}
			set
			{
				if (value > 0f && value <= 1f)
				{
					barPercentWidth = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 实例化一个默认的条形图的控件
		/// </summary>
		public HslBarChart()
		{
			InitializeComponent();
			format_left = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Near
			};
			format_right = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Far
			};
			format_center = new StringFormat
			{
				LineAlignment = StringAlignment.Center,
				Alignment = StringAlignment.Center
			};
			auxiliary_lines = new List<AuxiliaryLine>();
			pen_dash = new Pen(color_dash);
			pen_dash.DashStyle = DashStyle.Custom;
			pen_dash.DashPattern = new float[2]
			{
				5f,
				5f
			};
			InitializationColor();
			SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, value: true);
			SetStyle(ControlStyles.ResizeRedraw, value: true);
			SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
			SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
			ForeColor = Color.Black;
			if (GetService(typeof(IDesignerHost)) != null || LicenseManager.UsageMode == LicenseUsageMode.Designtime)
			{
				data_values = new int[5]
				{
					4,
					2,
					1,
					3,
					2
				};
			}
		}

		public bool IsDesignModel()
		{
			return GetService(typeof(IDesignerHost)) != null || LicenseManager.UsageMode == LicenseUsageMode.Designtime;
		}

		private void InitializationColor()
		{
			pen_normal?.Dispose();
			brush_deep?.Dispose();
			pen_normal = new Pen(color_deep);
			brush_deep = new SolidBrush(color_deep);
		}

		/// <summary>
		/// 设置柱形图的数据内容
		/// </summary>
		/// <param name="data">数据的集合</param>
		public void SetDataSource(int[] data)
		{
			data_values = data;
			data_texts = null;
			data_colors = null;
			Invalidate();
		}

		/// <summary>
		/// 设置柱形图的数据内容
		/// </summary>
		/// <param name="data">数据的集合</param>
		/// <param name="texts">底部的描述信息</param>
		public void SetDataSource(int[] data, string[] texts)
		{
			data_values = data;
			data_texts = texts;
			data_colors = null;
			Invalidate();
		}

		/// <summary>
		/// 设置柱形图的数据内容
		/// </summary>
		/// <param name="data">数据的集合</param>
		/// <param name="texts">底部的描述信息</param>
		/// <param name="colors">每个柱形图的颜色</param>
		public void SetDataSource(int[] data, string[] texts, Color[] colors)
		{
			data_values = data;
			data_texts = texts;
			data_colors = colors;
			Invalidate();
		}

		/// <summary>
		/// 重绘控件的
		/// </summary>
		/// <param name="e">重绘事件</param>
		protected override void OnPaint(PaintEventArgs e)
		{
			Graphics g = e.Graphics;
			g.SmoothingMode = SmoothingMode.HighQuality;
			g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			PaintHslControls(g, base.Width, base.Height);
			base.OnPaint(e);
		}

		/// <inheritdoc cref="M:HslControls.HslArrow.PaintHslControls(System.Drawing.Graphics,System.Single,System.Single)" />
		public void PaintHslControls(Graphics g, int width, int height)
		{
			if (!Authorization.iashdiadasbdnajsdhjaf())
			{
				return;
			}
			int[] array = data_values;
			int max = (array != null && array.Length != 0) ? HslHelper.CalculateMaxSectionFrom(data_values) : 5;
			if (value_max_left > 0)
			{
				max = value_max_left;
			}
			int offect_left = (int)g.MeasureString(max.ToString(), Font).Width + 3;
			if (offect_left < 50)
			{
				offect_left = 50;
			}
			int offect_right = 10;
			int offect_up = 25;
			int offect_down = 25;
			Point[] pointsCoordinate = new Point[3]
			{
				new Point(offect_left, offect_up - 8),
				new Point(offect_left, height - offect_down),
				new Point(width - offect_right, height - offect_down)
			};
			g.DrawLine(pen_normal, pointsCoordinate[0], pointsCoordinate[1]);
			g.DrawLine(pen_normal, pointsCoordinate[1], pointsCoordinate[2]);
			HslHelper.PaintTriangle(g, brush_deep, new Point(offect_left, offect_up - 8), 4, GraphDirection.Upward);
			for (int l = 0; l < auxiliary_lines.Count; l++)
			{
				auxiliary_lines[l].PaintValue = HslHelper.ComputePaintLocationY(max, value_min_left, height - offect_up - offect_down, auxiliary_lines[l].Value) + (float)offect_up;
			}
			if (!string.IsNullOrEmpty(value_title))
			{
				g.DrawString(value_title, Font, brush_deep, new Rectangle(0, 0, width - 1, offect_up), format_center);
			}
			for (int k = 0; k <= value_Segment; k++)
			{
				float valueTmpLeft = (float)((double)k * (double)(max - value_min_left) / (double)value_Segment + (double)value_min_left);
				float paintTmp = HslHelper.ComputePaintLocationY(max, value_min_left, height - offect_up - offect_down, valueTmpLeft) + (float)offect_up;
				if (IsNeedPaintDash(paintTmp))
				{
					g.DrawLine(pen_normal, offect_left - 4, paintTmp, offect_left - 1, paintTmp);
					g.DrawString(layoutRectangle: new RectangleF(0f, paintTmp - 19f, offect_left - 4, 40f), s: valueTmpLeft.ToString(), font: Font, brush: brush_deep, format: format_right);
					if (k > 0 && value_IsRenderDashLine)
					{
						g.DrawLine(pen_dash, offect_left, paintTmp, width - offect_right, paintTmp);
					}
				}
			}
			for (int j = 0; j < auxiliary_lines.Count; j++)
			{
				g.DrawLine(auxiliary_lines[j].GetPen(), offect_left - 4, auxiliary_lines[j].PaintValue, offect_left - 1, auxiliary_lines[j].PaintValue);
				g.DrawString(layoutRectangle: new RectangleF(0f, auxiliary_lines[j].PaintValue - 9f, offect_left - 4, 20f), s: auxiliary_lines[j].Value.ToString(), font: Font, brush: auxiliary_lines[j].LineTextBrush, format: format_right);
				g.DrawLine(auxiliary_lines[j].GetPen(), offect_left, auxiliary_lines[j].PaintValue, width - offect_right, auxiliary_lines[j].PaintValue);
			}
			if (data_values == null || data_values.Length == 0)
			{
				return;
			}
			float width_every = (float)(width - offect_left - 1 - offect_right) * 1f / (float)data_values.Length;
			for (int i = 0; i < data_values.Length; i++)
			{
				float paintTmp2 = HslHelper.ComputePaintLocationY(max, value_min_left, height - offect_up - offect_down, data_values[i]) + (float)offect_up;
				RectangleF rectangleF = new RectangleF((float)i * width_every + (1f - barPercentWidth) / 2f * width_every + (float)offect_left, paintTmp2, width_every * barPercentWidth, (float)(height - offect_down) - paintTmp2);
				Color rect_back_color = barBackColor;
				if (data_colors != null && i < data_colors.Length)
				{
					rect_back_color = data_colors[i];
				}
				if (useGradient)
				{
					if (rectangleF.Height > 0f)
					{
						using LinearGradientBrush brush2 = new LinearGradientBrush(new PointF(rectangleF.X, rectangleF.Y + rectangleF.Height), new PointF(rectangleF.X, rectangleF.Y), HslHelper.GetColorLight(rect_back_color), rect_back_color);
						g.FillRectangle(brush2, rectangleF);
					}
				}
				else
				{
					using Brush brush3 = new SolidBrush(rect_back_color);
					g.FillRectangle(brush3, rectangleF);
				}
				if (isShowBarValue)
				{
					using Brush brush = new SolidBrush(ForeColor);
					g.DrawString(layoutRectangle: new RectangleF((float)i * width_every + (float)offect_left - 50f, paintTmp2 - (float)Font.Height - 2f, width_every + 100f, Font.Height + 2), s: string.Format(showBarValueFormat, data_values[i]), font: Font, brush: brush, format: format_center);
				}
				if (data_texts != null && i < data_texts.Length)
				{
					g.DrawString(layoutRectangle: new RectangleF((float)i * width_every + (float)offect_left - 50f, height - offect_down - 1, width_every + 100f, offect_down + 1), s: data_texts[i], font: Font, brush: brush_deep, format: format_center);
				}
			}
		}

		private bool IsNeedPaintDash(float paintValue)
		{
			if (data_values == null)
			{
				return true;
			}
			for (int i = 0; i < auxiliary_lines.Count; i++)
			{
				if (Math.Abs(auxiliary_lines[i].PaintValue - paintValue) < (float)Font.Height)
				{
					return false;
				}
			}
			return true;
		}

		private float calculatMaxTextWidth(Graphics g)
		{
			string[] array = data_texts;
			if (array != null && array.Length != 0)
			{
				float max = 0f;
				for (int i = 0; i < data_texts.Length; i++)
				{
					float tmp = g.MeasureString(data_texts[i], Font).Width;
					if (max < tmp)
					{
						max = tmp;
					}
				}
				return max;
			}
			return 1f;
		}

		/// <summary>
		/// 新增一条左侧的辅助线，使用默认的文本颜色
		/// </summary>
		/// <param name="value">数据值</param>
		public void AddLeftAuxiliary(float value)
		{
			AddLeftAuxiliary(value, ColorLinesAndText);
		}

		/// <summary>
		/// 新增一条左侧的辅助线，使用指定的颜色
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		public void AddLeftAuxiliary(float value, Color lineColor)
		{
			AddLeftAuxiliary(value, lineColor, 1f, isDashLine: true);
		}

		/// <summary>
		/// 新增一条左侧的辅助线
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="lineThickness">线条宽度</param>
		/// <param name="isDashLine">是否是虚线</param>
		public void AddLeftAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
		{
			AddAuxiliary(value, lineColor, lineThickness, isDashLine, isLeft: true);
		}

		/// <summary>
		/// 新增一条右侧的辅助线，使用默认的文本颜色
		/// </summary>
		/// <param name="value">数据值</param>
		public void AddRightAuxiliary(float value)
		{
			AddRightAuxiliary(value, ColorLinesAndText);
		}

		/// <summary>
		/// 新增一条右侧的辅助线，使用指定的颜色
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		public void AddRightAuxiliary(float value, Color lineColor)
		{
			AddRightAuxiliary(value, lineColor, 1f, isDashLine: true);
		}

		/// <summary>
		/// 新增一条右侧的辅助线
		/// </summary>
		/// <param name="value">数据值</param>
		/// <param name="lineColor">线条颜色</param>
		/// <param name="lineThickness">线条宽度</param>
		/// <param name="isDashLine">是否是虚线的信息</param>
		public void AddRightAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine)
		{
			AddAuxiliary(value, lineColor, lineThickness, isDashLine, isLeft: false);
		}

		private void AddAuxiliary(float value, Color lineColor, float lineThickness, bool isDashLine, bool isLeft)
		{
			auxiliary_lines.Add(new AuxiliaryLine
			{
				Value = value,
				LineColor = lineColor,
				PenDash = new Pen(lineColor)
				{
					DashStyle = DashStyle.Custom,
					DashPattern = new float[2]
					{
						5f,
						5f
					}
				},
				PenSolid = new Pen(lineColor),
				IsDashStyle = isDashLine,
				IsLeftFrame = isLeft,
				LineThickness = lineThickness,
				LineTextBrush = new SolidBrush(lineColor)
			});
			Invalidate();
		}

		/// <summary>
		/// 移除所有的指定值的辅助曲线，包括左边的和右边的
		/// </summary>
		/// <param name="value"></param>
		public void RemoveAuxiliary(float value)
		{
			int removeCount = 0;
			for (int i = auxiliary_lines.Count - 1; i >= 0; i--)
			{
				if (auxiliary_lines[i].Value == value)
				{
					auxiliary_lines[i].Dispose();
					auxiliary_lines.RemoveAt(i);
					removeCount++;
				}
			}
			if (removeCount > 0)
			{
				Invalidate();
			}
		}

		/// <summary>
		/// 移除所有的辅助线
		/// </summary>
		public void RemoveAllAuxiliary()
		{
			int removeCount = auxiliary_lines.Count;
			auxiliary_lines.Clear();
			if (removeCount > 0)
			{
				Invalidate();
			}
		}

		/// <summary> 
		/// 清理所有正在使用的资源。
		/// </summary>
		/// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <summary> 
		/// 设计器支持所需的方法 - 不要修改
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			SuspendLayout();
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
			BackColor = System.Drawing.Color.Transparent;
			ForeColor = System.Drawing.Color.Black;
			base.Name = "HslBarChart";
			base.Size = new System.Drawing.Size(440, 264);
			ResumeLayout(false);
		}
	}
}
